import React from 'react'
//
import * as THREE from 'three'
import { useFrame, useThree } from '@react-three/fiber'
//
import useTextToSpeech from '../TextToSpeech'
import { narrationStore, loadNarrations } from './narrationStore'

// 负责：
// 1) 加载 artworks.json -> narrationStore
// 2) 每帧根据玩家位置/朝向检测最近的讲解区
// 3) 调用 TTS 播放/打断（一次只播一个）

const toVec3 = (a: [number, number, number]) => new THREE.Vector3(a[0], a[1], a[2])

// 预留：若后续恢复可见性检测再启用

const NarrationSystem: React.FC = () => {
  const { camera } = useThree()

  // 加载数据表（只运行一次）
  React.useEffect(() => {
    let mounted = true
    ;(async () => {
      try {
        const res = await fetch(new URL('./artworks.json', import.meta.url))
        const json = await res.json()
        if (!mounted) return
        loadNarrations(json)
      } catch (e) {
        console.warn('加载artworks.json失败', e)
      }
    })()
    return () => { mounted = false }
  }, [])

  // TTS
  const tts = useTextToSpeech({ onStatusChange: () => {} })

  const armingRef = React.useRef<{ id: string; since: number } | null>(null)
  const [readyId, setReadyId] = React.useState<string>('')

  // 背景音乐控制：不讲解时持续播放，讲解时停止
  const playBG = React.useCallback(() => {
    try { (window as unknown as { audioManager?: { playBackgroundMusic?: () => void } }).audioManager?.playBackgroundMusic?.() } catch { /* noop */ }
  }, [])
  const stopBG = React.useCallback(() => {
    try { (window as unknown as { audioManager?: { stopBackgroundMusic?: () => void } }).audioManager?.stopBackgroundMusic?.() } catch { /* noop */ }
  }, [])
  React.useEffect(() => { playBG() }, [playBG])

  const pickCandidate = React.useCallback(() => {
    let best: { id: string; dist: number } | null = null
    const camPos = camera.position
    const forward = new THREE.Vector3(); camera.getWorldDirection(forward)
    forward.y = 0; forward.normalize()

    for (const zone of narrationStore.zones.values()) {
      // 仅挑选左右两侧墙体四幅 + 右侧四幅，共八幅
      const id = zone.id
      const allow = (
        id === 'zhengjing' || id === 'weixun' || id === 'yijiutianmei' || id === 'zhuangtianmei' ||
        id === 'yiriyou' || id === 'dudu' || id === 'taohua' || id === 'zhuangjingshen'
      )
      if (!allow) continue
      const center = toVec3(zone.position)
      const d = new THREE.Vector2(center.x - camPos.x, center.z - camPos.z).length()
      // 半径阈值：必须靠近到阈值内才认为可候选
      const R = 1.2
      if (d > R) continue
      // 面朝画作（水平夹角≤35°）
      const forward = new THREE.Vector3(); camera.getWorldDirection(forward)
      forward.y = 0; forward.normalize()
      const toCenter = new THREE.Vector3(center.x - camPos.x, 0, center.z - camPos.z).normalize()
      const cos = THREE.MathUtils.clamp(forward.dot(toCenter), -1, 1)
      const deg = Math.acos(cos) * 180 / Math.PI
      if (deg > 35) continue
      if (!best || d < best.dist) best = { id: zone.id, dist: d }
    }
    return best?.id || ''
  }, [camera])

  // 播放一个指定id
  const playId = React.useCallback(async (id: string) => {
    const data = narrationStore.data.get(id)
    if (!data) return
    narrationStore.currentId = id
    narrationStore.status = 'playing'
    // 讲解开始前，停止背景音乐
    stopBG()
    try {
      await tts.speakText(data.ttsText)
    } catch {
      // ignore
    } finally {
      narrationStore.status = 'cooldown'
      narrationStore.lastEndAt = performance.now()
      // 讲解结束后，恢复背景音乐
      playBG()
      setTimeout(() => {
        if (narrationStore.status === 'cooldown' && narrationStore.currentId === id) {
          narrationStore.status = 'idle'
          narrationStore.currentId = ''
        }
      }, data.trigger.cooldownMs || 3000)
    }
  }, [tts, stopBG, playBG])

  // 自动模式：进入后自动播放（无E键提示）
  React.useEffect(() => {
    if (!narrationStore.autoMode) return
    if (!readyId) return
    // 若已在cooldown或playing则忽略
    if (narrationStore.status !== 'idle') return
    const id = readyId
    setReadyId('')
    playId(id)
  }, [readyId, playId])

  useFrame(() => {
    const now = performance.now()
    const id = pickCandidate()

    // 若正在播放且靠近了另一幅图：立即中断并切换
    if (narrationStore.status === 'playing') {
      if (narrationStore.autoMode && id && id !== narrationStore.currentId) {
        try { tts.stopPlayback() } catch { /* ignore */ }
        narrationStore.status = 'idle'
        narrationStore.currentId = ''
        setReadyId('')
        narrationStore.readyId = ''
        // 立即播放新的
        playId(id)
      }
      return
    }
    if (narrationStore.status === 'cooldown') return
    if (!id) { armingRef.current = null; setReadyId(''); narrationStore.readyId = ''; return }

    if (!armingRef.current || armingRef.current.id !== id) {
      armingRef.current = { id, since: now }
      return
    }
    // 驻留计时
    const dwell = 300
    if (now - armingRef.current.since < dwell) return
    // 自动模式：把候选记下，由上面的 effect 决定是否自动播放
    narrationStore.status = 'idle'
    setReadyId(id)
    narrationStore.readyId = id
  })

  return null
}

export default NarrationSystem


 